using System;
using lucere.io.concurrency;

namespace lucere.io
{
	public interface IDirectory : IDisposable
	{
		/// <summary>
		/// Set the LockFactory that this Directory instance should
		/// use for its locking implementation.  Each * instance of
		/// ILockFactory should only be used for one directory (ie,
		/// do not share a single instance across multiple
		/// Directories).
		/// Get the LockFactory that this Directory instance is
		/// using for its locking implementation.  Note that this
		/// may be null for Directory implementations that provide
		/// their own locking implementation.
		/// </summary>
		ILockFactory LockFactory { get; set; }

		/// <returns>Returns an array of strings, one for each file in the directory.</returns>
		string[] ListAll();

		/// <returns>Returns true if a file with the given name exists.</returns>
		bool FileExists(string name);

		/// <returns>The time the named file was last modified.</returns>
		long FileModified(string name);

		/// <summary>
		/// Set the modified time of an existing file to now.
		/// </summary>
		void TouchFile(string name);

		/// <summary>
		/// Removes an existing file in the directory.
		/// </summary>
		/// <param name="name"></param>
		void DeleteFile(string name);

		/// <returns>The length of a file in the directory.</returns>
		long FileLength(string name);

		/// <summary>
		/// Creates a new, empty file in the directory with the given name.
		/// </summary>
		/// <param name="name"></param>
		/// <returns>a stream writing this file.</returns>
		IIndexOutput CreateOutput(string name);

		/// <summary>
		///	Ensure that any writes to this file are moved to
		/// stable storage.  Lucene uses this to properly commit
		/// changes to the index, to prevent a machine/OS crash
		/// from corrupting the index.
		/// </summary>
		/// <param name="name"></param>
		void Sync(string name);

		/// <summary>Returns a stream reading an existing file, with the
		/// specified read buffer size.  The particular Directory
		/// implementation may ignore the buffer size.  Currently
		/// the only Directory implementations that respect this
		/// parameter are {@link FSDirectory} and {@link
		/// org.apache.lucene.index.CompoundFileReader}.
		/// </summary>
		/// <param name="name"></param>
		/// <returns></returns>
		IIndexInput OpenInput(string name);

		/// <summary>
		/// Construct a <see>ILock</see>
		/// </summary>
		/// <param name="name">the name of the lock file</param>
		/// <returns></returns>
		ILock MakeLock(string name);

		/// <summary>
		/// Attempt to clear (forcefully unlock and remove) the
		/// specified lock.  Only call this at a time when you are
		/// certain this lock is no longer in use.
		/// </summary>
		/// <param name="name">name of the lock to be cleared.</param>
		void ClearLock(string name);

		/// <summary>
		/// Return a string identifier that uniquely differentiates
		/// this Directory instance from other Directory instances.
		/// This ID should be the same if two Directory instances
		/// (even in different JVMs and/or on different machines)
		/// are considered "the same index".  This is how locking
		/// "scopes" to the right index.
		/// </summary>
		string LockId{get;}


		/// <summary>
		/// Copy contents of a directory src to a directory dest.
		/// If a file in src already exists in dest then the
		/// one in dest will be blindly overwritten.
		/// 
		/// <p><b>NOTE:</b> the source directory cannot change
		/// while this method is running.  Otherwise the results
		/// are undefined and you could easily hit a
		/// FileNotFoundException.
		/// <p><b>NOTE:</b> this method only copies files that look
		/// like index files (ie, have extensions matching the
		/// known extensions of index files).
		/// </summary>
		/// <param name="src">source directory</param>
		/// <param name="dest">destination directory</param>
		/// <param name="closeDirSrc">if <code>true</code>, call Dispose() method on source directory</param>
		void Copy(IDirectory src, IDirectory dest, bool closeDirSrc);
	}
}